#include <QDate>
#include <QDateTime>
#include <QMessageBox>
#include "historydialog.h"
#include "ui_historydialog.h"
#include "utils/xio.h"

HistoryDialog::HistoryDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::HistoryDialog)
{
    ui->setupUi(this);
    QDate currentDate = QDateTime::currentDateTime().date();
    this->initDateComboBox(ui->comboBoxStartDate, currentDate);
    this->initDateComboBox(ui->comboBoxEndDate, currentDate);
}

void HistoryDialog::initDateComboBox(QComboBox* dateComboBox, QDate& newestDate) {
    dateComboBox->addItem(tr("Unlimited"));
    for (int i = 0; i < 30; ++ i) {
        QDate date = newestDate.addDays(-i);
        dateComboBox->addItem(date.toString("yyyy-MM-dd"));
    }
}

void HistoryDialog::syncHistoryDirPath(const QString& historyDirPath) {
    this->historyDirPath = historyDirPath;
    this->reloadHistoryTable("");
}

void HistoryDialog::reloadHistoryTable(const QString& keyword) {
    ui->tableWidgetHistory->setRowCount(0);
    QStringList historyPaths;
    XIO::getPaths(this->historyDirPath, historyPaths, true);
    QString dateTimeStr;
    QString content;
    for (QString& historyPath : historyPaths) {
        if (keyword.length() != 0) {
            this->insertTableByChatHistory(keyword, historyPath);
            continue;
        }
        int finalIdx = 0;
        QString questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        while (QFileInfo(questionPath).isFile())
            questionPath = QString("%1/%2.question").arg(historyPath).arg(++ finalIdx);
        -- finalIdx;
        questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        XIO::getName(historyPath, dateTimeStr);
        XIO::readText(questionPath, content, 1);
        this->insertTable(
            QDateTime::fromString(dateTimeStr, ChatHistory::DATE_FORMAT),
            finalIdx, content
        );
    }
}

void HistoryDialog::reloadHistoryTable(
    const QString& keyword, const QDateTime& dateTime, bool isStartDateTime
) {
    ui->tableWidgetHistory->setRowCount(0);
    QStringList historyPaths;
    XIO::getPaths(this->historyDirPath, historyPaths, true);
    QString dateTimeStr;
    QString content;
    for (QString& historyPath : historyPaths) {
        XIO::getName(historyPath, dateTimeStr);
        QDateTime dt = QDateTime::fromString(dateTimeStr, ChatHistory::DATE_FORMAT);
        if (isStartDateTime) {
            if (dt < dateTime)
                continue;
        } else {
            if (dt.date() > dateTime.date())
                continue;
        }
        if (keyword.length() != 0) {
            this->insertTableByChatHistory(keyword, historyPath);
            continue;
        }
        int finalIdx = 0;
        QString questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        while (QFileInfo(questionPath).isFile())
            questionPath = QString("%1/%2.question").arg(historyPath).arg(++ finalIdx);
        -- finalIdx;
        questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        XIO::readText(questionPath, content, 1);
        this->insertTable(dt, finalIdx, content);
    }
}

bool HistoryDialog::reloadHistoryTable(
    const QString& keyword,
    const QDateTime& startDateTime,
    const QDateTime& endDateTime
) {
    if (endDateTime < startDateTime)
        return false;
    ui->tableWidgetHistory->setRowCount(0);
    QStringList historyPaths;
    XIO::getPaths(this->historyDirPath, historyPaths, true);
    QString dateTimeStr;
    QString content;
    for (QString& historyPath : historyPaths) {
        XIO::getName(historyPath, dateTimeStr);
        QDateTime dt = QDateTime::fromString(dateTimeStr, ChatHistory::DATE_FORMAT);
        if (dt < startDateTime)
            continue;
        if (dt.date() > endDateTime.date())
            continue;
        if (keyword.length() != 0) {
            this->insertTableByChatHistory(keyword, historyPath);
            continue;
        }
        int finalIdx = 0;
        QString questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        while (QFileInfo(questionPath).isFile())
            questionPath = QString("%1/%2.question").arg(historyPath).arg(++ finalIdx);
        -- finalIdx;
        questionPath = QString("%1/%2.question").arg(historyPath).arg(finalIdx);
        XIO::readText(questionPath, content, 1);
        this->insertTable(dt, finalIdx, content);
    }
    return true;
}

HistoryDialog::~HistoryDialog()
{
    delete ui;
}

void HistoryDialog::on_pushButtonSearch_clicked()
{
    QString keyword = ui->lineEditSearch->text().trimmed();
    QString startDateStr = ui->comboBoxStartDate->currentText();
    QString endDateStr = ui->comboBoxEndDate->currentText();
    if (startDateStr == tr("Unlimited")) {
        if (endDateStr == tr("Unlimited")) {
            this->reloadHistoryTable(keyword);
            return;
        }
        this->reloadHistoryTable(keyword, QDateTime::fromString(endDateStr, "yyyy-MM-dd"), false);
        return;
    } else if (endDateStr == tr("Unlimited")) {
        this->reloadHistoryTable(keyword, QDateTime::fromString(startDateStr, "yyyy-MM-dd"), true);
        return;
    }
    if (!this->reloadHistoryTable(
        keyword,
        QDateTime::fromString(startDateStr, "yyyy-MM-dd"),
        QDateTime::fromString(endDateStr, "yyyy-MM-dd")
    )) {
        QMessageBox::warning(this, tr("Invalid date range"), tr("Start date is bigger than end date!"));
    }
}

void HistoryDialog::insertTable(const QDateTime& dateTime, const int index, const QString& content) {
    int rowIndex = ui->tableWidgetHistory->rowCount();
    ui->tableWidgetHistory->insertRow(rowIndex);
    
    auto dtItem = new QTableWidgetItem(dateTime.toString(this->DATE_DISPLAY_FORMAT));
    auto idxItem = new QTableWidgetItem(QString("%1").arg(index));
    auto queItem = new QTableWidgetItem(content);
    
    dtItem->setTextAlignment(Qt::AlignCenter);
    idxItem->setTextAlignment(Qt::AlignCenter);
    queItem->setTextAlignment(Qt::AlignCenter);
    
    ui->tableWidgetHistory->setItem(rowIndex, 0, dtItem);
    ui->tableWidgetHistory->setItem(rowIndex, 1, idxItem);
    ui->tableWidgetHistory->setItem(rowIndex, 2, queItem);
}

void HistoryDialog::insertTableByChatHistory(
    const QString& keyword, const QString& historyPath
) {
    ChatHistory history;
    history.load(historyPath);
    QVector<int> indexVector;
    history.find(keyword, indexVector);
    if (indexVector.length() == 0)
        return;
    QString content;
    for (int index : indexVector) {
        XIO::readText(
            QString("%1/%2.question").arg(historyPath).arg(index)
        , content, 1);
        this->insertTable(history.getDateTime(), index, content);
    }
}

void HistoryDialog::on_tableWidgetHistory_cellActivated(int row, int)
{
    QDateTime dateTime = QDateTime::fromString(
        ui->tableWidgetHistory->item(row, 0)->text(), this->DATE_DISPLAY_FORMAT
    );
    ChatHistory chatHistory;
    chatHistory.load(QString("%1/%2").arg(this->historyDirPath).arg(
        dateTime.toString(ChatHistory::DATE_FORMAT)
    ));
    int index = ui->tableWidgetHistory->item(row, 1)->text().toInt();
    emit signal_showHistory(chatHistory, index);
}
